package com.niiwoo.civet.trade.service.local.kaola;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.rpc.RpcContext;
import com.alibaba.fastjson.JSON;
import com.niiwoo.civet.account.dto.common.sendmessage.RepaymentSuccessDTO;
import com.niiwoo.civet.account.enums.RepaymentTypeLetterEnum;
import com.niiwoo.civet.account.service.MessageSendDubboService;
import com.niiwoo.civet.trade.constant.RabbitConstant;
import com.niiwoo.civet.trade.dao.entity.*;
import com.niiwoo.civet.trade.dao.mapper.*;
import com.niiwoo.civet.trade.dto.FollowWorkTaskRepaymentDTO;
import com.niiwoo.civet.trade.dto.ProjectBorrowerAmountSumDTO;
import com.niiwoo.civet.trade.dto.common.RefundCallBackForAccountDTO;
import com.niiwoo.civet.trade.dto.kaola.NotifyRepaymentResult;
import com.niiwoo.civet.trade.dto.kaola.Result;
import com.niiwoo.civet.trade.enums.ProjectPlanStatusEnum;
import com.niiwoo.civet.trade.enums.RepayStatusEnum;
import com.niiwoo.civet.trade.enums.kaola.BadLoansRepayMethodEmun;
import com.niiwoo.civet.trade.enums.kaola.KaoLaLiCaiIsPassiveEnum;
import com.niiwoo.civet.trade.enums.kaola.KaoLaLiCaiRepayTypeEnum;
import com.niiwoo.civet.trade.utils.RepaymentUtil;
import com.niiwoo.civet.user.dto.request.QueryUserBasicInfoRequestDTO;
import com.niiwoo.civet.user.dto.response.QueryBasicInfoResponseDTO;
import com.niiwoo.civet.user.enums.QueryBasicInfoEnum;
import com.niiwoo.civet.user.service.UserBasicInfoDubboService;
import com.niiwoo.tripod.base.utils.DateUtils;
import com.niiwoo.tripod.service.component.SnowflakeIdWorker;
import com.niiwoo.tripod.tiancheng.component.TianChengRefundEventService;
import com.niiwoo.tripod.tiancheng.request.df.ProjectRefundEventRequest;
import com.niiwoo.tripod.tiancheng.request.df.ProjectRefundEventRequestDetail;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
 * 考拉理财申请借款接口
 *
 * @author daizhiyue
 * @dateTime 2018-01-01
 */
@Service
@Slf4j
public class KaoLaLiCaiApplyService {

    @Autowired
    private KaoLaRealRepaymentMapperExt kaoLaRealRepaymentMapperExt;

    @Autowired
    private KaoLaLiCaiRepaymentService kaoLaLiCaiRepaymentService;

    @Autowired
    private KaoLaProjectRepaymentMapperExt kaoLaProjectRepaymentMapperExt;

    @Autowired
    private ProjectMapper projectMapper;

    @Autowired
    private SnowflakeIdWorker snowflakeIdWorker;

    @Autowired
    private ProjectBorrowerPlanMapperExt projectBorrowerPlanMapperExt;

    @Autowired
    private KaoLaOrderInfoMapperExt kaoLaOrderInfoMapperExt;

    @Autowired
    private ProjectBorrowerSummaryMapperExt projectBorrowerSummaryMapperExt;

    @Autowired
    private KaoLaLiCaiRepaymentCallbackService kaoLaLiCaiRepaymentCallbackService;

    @Reference(version = "1.0.0")
    private UserBasicInfoDubboService userBasicInfoDubboService;

    @Reference(version = "1.0.0")
    private TianChengRefundEventService tianChengRefundEventService;

    @Reference(version = "1.0.0")
    private MessageSendDubboService messageSendDubboService;

    private static final Integer KAOLALICAI_REAPY_HAVE_IN_HAND = 3; // 进⾏中
    private static final Integer KAOLALICAI_REAPY_FAIL = 4; // 失败
    private static final Integer KAOLALICAI_REAPY_SUCCESS = 5; // 成功


    /**
     * 考拉理财还款回调处理（计划任务用）
     *
     * @param repaymentResult
     */
    public void notifyRepaymentForJob(NotifyRepaymentResult repaymentResult) {
        // 判断还款结果
        if (KAOLALICAI_REAPY_HAVE_IN_HAND.equals(repaymentResult.getStatus())) {
            log.info("考拉理财还款回调--定时主动请求还款结果任务-还款结果状态为处理中--不作处理");
        } else {
            getSelfProxy().notifyRepayment(repaymentResult);
        }
    }

    /**
     * 考拉理财还款回调
     *
     * @param repaymentResult
     * @return Result
     * @throws Exception
     */
    public Result notifyRepayment(NotifyRepaymentResult repaymentResult) {
        Result result = new Result(Result.SUCCESS_RET);
        try {
            // 判断还款结果
            if (repaymentResult == null || null == repaymentResult.getSerial_no()
                    || null == repaymentResult.getSubject_id()) {
                log.info("考拉理财还款回调--还款结果的流水号或标的ID为空!");
                result.setFailureMessage("还款结果的流水号或标的ID为空!");
                return result;
            }

            // 还款记录
            KaoLaRealRepayment klRepayment = null;
            // 用户主动还款
            if (!repaymentResult.getIs_passive()) {
                klRepayment = kaoLaRealRepaymentMapperExt.selectPaymentBySerialNoAndSubjectIdForUpdate(repaymentResult.getSerial_no(),
                        repaymentResult.getSubject_id());
                if (klRepayment == null) {
                    result.setFailureMessage("考拉理财还款回调--未查询到对应的还款记录信息!");
                }
            } else {
                KaoLaRealRepayment kaoLaRealrePayment = null;
                // 判断是否存在重复代偿或者重复回购
                if (KaoLaLiCaiRepayTypeEnum.REPAY_ADVANCE.getCode().equals(repaymentResult.getType())) {
                    //代偿
                    kaoLaRealrePayment = kaoLaRealRepaymentMapperExt.selectSuccessAdvanceByProjectIdAndPeriod(
                            Long.parseLong(repaymentResult.getSubject_id()), repaymentResult.getRepay_no());
                    if (kaoLaRealrePayment != null) {
                        log.info("考拉理财还款回调--当前项目" + repaymentResult.getSubject_id() + ",期数" + repaymentResult.getRepay_no() + "已经代偿");
                        result.setFailureMessage("当前项目已经代偿!");
                    }
                } else if (KaoLaLiCaiRepayTypeEnum.REPAY_BUYBACK.getCode().equals(repaymentResult.getType())) {
                    ///考拉回购
                    // 判断考拉是否已经发过回购通知
                    kaoLaRealrePayment = kaoLaRealRepaymentMapperExt.selectPassiveKaoLaBuyBack(Long.valueOf(repaymentResult.getSubject_id()));
                    if (kaoLaRealrePayment != null) {
                        log.info("考拉理财还款回调--当前项目" + repaymentResult.getSubject_id() + "已经回购");
                        result.setFailureMessage("当前项目已经回购!");
                    }
                } else if (KaoLaLiCaiRepayTypeEnum.REPAY_BATCHPAYMENT.getCode().equals(repaymentResult.getType())) {
                    ///考拉批扣
                    // 判断考拉是否已经发过批扣通知
                    kaoLaRealrePayment = kaoLaRealRepaymentMapperExt.selectPassiveKaoLaBatchRepayment(Long.parseLong(repaymentResult.getSubject_id()), repaymentResult.getRepay_no());
                    if (kaoLaRealrePayment != null) {
                        log.info("考拉理财还款回调--当前项目" + repaymentResult.getSubject_id() + "已经批扣");
                        result.setFailureMessage("当前项目已经批扣!");
                    }
                }

                // 不存在相关记录，才插入记录
                if (kaoLaRealrePayment == null) {
                    klRepayment = addRepaymentRecord(repaymentResult, result);
                }
            }

            // 判断还款记录是否为空
            if (klRepayment == null) {
                log.info("考拉理财还款回调--" + result.getMessage() + "!repay_serial_no：{},subject_id:{}", repaymentResult.getSerial_no(),
                        repaymentResult.getSubject_id());
                return result;
            }

            // 查询项目表信息
            ProjectBorrowerSummary summary = projectBorrowerSummaryMapperExt.selectByPrimaryKeyForUpdate(Long.parseLong(repaymentResult.getSubject_id()));

            KaoLaRealRepayment kaoLaRealRepayment = kaoLaLiCaiRepaymentService.getBuyBackRepayment(Long.parseLong(repaymentResult.getSubject_id()));
            if (!repaymentResult.getIs_passive() && KaoLaLiCaiRepayTypeEnum.REPAY_OVERDUE.getCode().equals(repaymentResult.getType())) {
                //判断是否回购
                if(kaoLaRealRepayment != null && summary.getRepayStatus().equals(RepayStatusEnum.NORMAL.getCode())) {
                    repaymentResult.setType(KaoLaLiCaiRepayTypeEnum.REPAY_NOMAL.getCode());
                    repaymentResult.setRepay_no(summary.getCurrentPeriod());
                    klRepayment.setRepayNo(summary.getCurrentPeriod());
                    klRepayment.setRepayMethod(KaoLaRealRepayment.RepayMethodEnum.NORMAL_REPAY.getType());
                } else if(kaoLaRealRepayment != null && summary.getRepayStatus().equals(RepayStatusEnum.OVERDUE.getCode())) {
                    repaymentResult.setType(KaoLaLiCaiRepayTypeEnum.REPAY_OVERDUE.getCode());
                    repaymentResult.setRepay_no(summary.getCurrentPeriod());
                    klRepayment.setRepayNo(summary.getCurrentPeriod());
                    klRepayment.setRepayMethod(KaoLaRealRepayment.RepayMethodEnum.OVERDUE_REPAY.getType());
                }
            }


            // 更新考拉还款记录
            updateRepaymentRecord(repaymentResult, klRepayment);

            if (repaymentResult.getOverdue_interest() == null) {
                repaymentResult.setOverdue_interest(BigDecimal.ZERO);
            }

            if (repaymentResult.getInterest_split() == null) {
                repaymentResult.setInterest_split(BigDecimal.ZERO);
            }

            Long projectId = Long.parseLong(repaymentResult.getSubject_id());// 项目ID
            Integer period = repaymentResult.getRepay_no();// 还款期数
            RefundCallBackForAccountDTO dto = new RefundCallBackForAccountDTO();
            dto.setProjectId(projectId);
            dto.setCurrentPeriod(period);
            dto.setBorrowerUserId(summary.getBorrowerUserId());
            RepaymentTypeLetterEnum repaymentTypeLetterEnum = summary.getCurrentPeriod().equals(summary.getTotalPeriod()) ? RepaymentTypeLetterEnum.REPAYMENT_SUCCESS_COMPLETE : RepaymentTypeLetterEnum.REPAYMENT_SUCCESS;

            // 还款回调状态成功，更改你我金融还款计划
            if (KAOLALICAI_REAPY_SUCCESS.equals(repaymentResult.getStatus())) {
                if (KaoLaLiCaiRepayTypeEnum.REPAY_NOMAL.getCode().equals(repaymentResult.getType())) {
                    //考拉理财正常还款回调
                    result = kaoLaLiCaiRepaymentCallbackService.nomalRepayCallback(repaymentResult);

                } else if (KaoLaLiCaiRepayTypeEnum.REPAY_SETTLE.getCode().equals(repaymentResult.getType())) {
                    //提前还款
                    result = kaoLaLiCaiRepaymentCallbackService.settleRepayCallback(repaymentResult);
                    // 更新考拉还款计划
                    getSelfProxy().repayBeforeUpdateKaoLaProjectRepayment(klRepayment.getProjectId(), klRepayment.getRepayNo());
                    repaymentTypeLetterEnum = RepaymentTypeLetterEnum.REPAYMENT_SUCCESS_ADVANCE;

                } else if (KaoLaLiCaiRepayTypeEnum.REPAY_OVERDUE.getCode().equals(repaymentResult.getType())) {
                    if (klRepayment.getRepayMethod().equals(KaoLaRealRepayment.RepayMethodEnum.OVERDUE_REPAY.getType())) {
                        //逾期还款
                        result = kaoLaLiCaiRepaymentCallbackService.overDueCallback(repaymentResult);
                    } else if (klRepayment.getRepayMethod().equals(KaoLaRealRepayment.RepayMethodEnum.BAD_DEBT_REPAY.getType())) {
                        //严重逾期还款(严重逾期还全部)
                        result = kaoLaLiCaiRepaymentCallbackService.settleBadDebtDue(repaymentResult, klRepayment);
                        if (BadLoansRepayMethodEmun.SECOND_TIME_BAD_DEBT_REPAY.getCode().equals(klRepayment.getBadLoansRepayMethod())) {
                            //坏账还款-结清(第二次将坏账那期之后的所有结清））
                            // 更新考拉还款计划
                            getSelfProxy().repayBeforeUpdateKaoLaProjectRepayment(klRepayment.getProjectId(), klRepayment.getRepayNo());
                            repaymentTypeLetterEnum = RepaymentTypeLetterEnum.REPAYMENT_SUCCESS_COMPLETE;
                        }
                    }

                } else if (KaoLaLiCaiRepayTypeEnum.REPAY_ADVANCE.getCode().equals(repaymentResult.getType()) && result.isSuccess()) {
                    //代偿
                    result = kaoLaLiCaiRepaymentCallbackService.advanceRepayCallback(repaymentResult);
                } else if (KaoLaLiCaiRepayTypeEnum.REPAY_BUYBACK.getCode().equals(repaymentResult.getType()) && result.isSuccess()) {
                    //考拉回购
                    result = kaoLaLiCaiRepaymentCallbackService.buyBackCallback(repaymentResult);
                } else if (KaoLaLiCaiRepayTypeEnum.REPAY_BATCHPAYMENT.getCode().equals(repaymentResult.getType()) && result.isSuccess()) {
                    //考拉批扣(还是正常还款操作)
                    result = kaoLaLiCaiRepaymentCallbackService.nomalRepayCallback(repaymentResult);
                }

                if (result.isSuccess()) {
                    if (KaoLaLiCaiRepayTypeEnum.REPAY_ADVANCE.getCode().equals(repaymentResult.getType()) ||
                            KaoLaLiCaiRepayTypeEnum.REPAY_BUYBACK.getCode().equals(repaymentResult.getType())) {
                        repaymentTypeLetterEnum = null;
                    }
                    if (repaymentTypeLetterEnum != null) {
                        repaymentSuccessPushLetterToBorrowerAsyn(summary, repaymentTypeLetterEnum, repaymentResult);
                    }
                    sendTianCheng(dto);
                    //通知app
                    sendMqMsgToApp(dto);

                    //清偿债权
                    kaoLaLiCaiRepaymentCallbackService.updateCreditorStatus2Settlement(repaymentResult, klRepayment);
                }
            } else {
                // 正常还款/逾期还款/提前结清失败才发消息
                if (KaoLaLiCaiRepayTypeEnum.REPAY_NOMAL.getCode().equals(repaymentResult.getType())
                        || KaoLaLiCaiRepayTypeEnum.REPAY_SETTLE.getCode().equals(repaymentResult.getType())
                        || KaoLaLiCaiRepayTypeEnum.REPAY_OVERDUE.getCode().equals(repaymentResult.getType())) {
                    result = kaoLaLiCaiRepaymentCallbackService.sendRepaymentFailMessage(repaymentResult);
                }
            }
        } catch (Exception e) {
            log.error("考拉还款回调处理异常!projectId：" + repaymentResult.getSubject_id(), e);
            result.setFailureMessage("考拉理财还款回调处理异常");
        }

        return result;
    }


    /**
     * 获取自身代理
     *
     * @return
     */
    private KaoLaLiCaiApplyService getSelfProxy() {
        return (KaoLaLiCaiApplyService) AopContext.currentProxy();
    }


    /**
     * @param repaymentResult
     * @param klRepayment
     * @Description 更新考拉还款记录
     */
    private void updateRepaymentRecord(NotifyRepaymentResult repaymentResult, KaoLaRealRepayment klRepayment) {
        KaoLaRealRepayment klRepaymentForUpdate = new KaoLaRealRepayment();
        klRepaymentForUpdate.setId(klRepayment.getId());
        Integer status = repaymentResult.getStatus();// 还款回调状态
        Byte niiwooStatus = KaoLaRealRepayment.NiiwooStatusEnum.REPAY_FAILED.getStatus();
        if (KAOLALICAI_REAPY_FAIL.equals(status)) {
            niiwooStatus = KaoLaRealRepayment.NiiwooStatusEnum.REPAY_FAILED.getStatus();
        } else if (KAOLALICAI_REAPY_SUCCESS.equals(status)) {
            niiwooStatus = KaoLaRealRepayment.NiiwooStatusEnum.REPAY_SUCCESS.getStatus();
        }
        klRepaymentForUpdate.setNiiwooRepayStatus(niiwooStatus);
        klRepaymentForUpdate.setRepayType(repaymentResult.getType());
        klRepaymentForUpdate.setCreditorAttorn(repaymentResult.getCreditor_attorn());
        klRepaymentForUpdate.setRepayCallbackStatus((byte) status.intValue());
        klRepaymentForUpdate.setRepayCallbackTips(repaymentResult.getMsg());
        klRepaymentForUpdate.setUpdateTime(new Date());
        kaoLaRealRepaymentMapperExt.updateByPrimaryKeySelective(klRepaymentForUpdate);
    }


    @Transactional(rollbackFor = Exception.class)
    public void repayBeforeUpdateKaoLaProjectRepayment(Long projectId, Integer period) {
        log.info("考拉理财还款回调--重新计算考拉还款计划：{}", projectId);
        List<ProjectBorrowerPlan> repaymentList = projectBorrowerPlanMapperExt.selectByProjectIdAndPeriodsList(projectId, period);
        for (ProjectBorrowerPlan projectBorrowerPlan : repaymentList) {
            //本金+平台管理费
            BigDecimal niiwooRepayAmount = projectBorrowerPlan.getCapital().add(projectBorrowerPlan.getManagementFee());
            KaoLaProjectRepayment kaoLaProjectRepayment = kaoLaProjectRepaymentMapperExt.selectByProjectIdAndPeriod(projectBorrowerPlan.getProjectId(), projectBorrowerPlan.getCurrentPeriod());
            if (null == kaoLaProjectRepayment) {
                continue;
            }
            //本金+平台管理费-考拉利率还款计划还款本金
            BigDecimal platformManagerFee = niiwooRepayAmount.subtract(kaoLaProjectRepayment.getRepayPrincipal());

            KaoLaProjectRepayment updateKaoLaProjectRepayment = new KaoLaProjectRepayment();
            updateKaoLaProjectRepayment.setId(kaoLaProjectRepayment.getId());
            updateKaoLaProjectRepayment.setPlatformManageFee(platformManagerFee);
            kaoLaProjectRepaymentMapperExt.updateByPrimaryKeySelective(updateKaoLaProjectRepayment);
        }
    }

    /**
     * @param repaymentResult
     * @param result
     * @return KaoLaRealrePayment
     * @Description 添加考拉被动还款记录
     */
    private KaoLaRealRepayment addRepaymentRecord(NotifyRepaymentResult repaymentResult, Result result) {
        // 插入还款记录
        KaoLaRealRepayment kaoLaRealrePayment = new KaoLaRealRepayment();
        // 项目ID
        Long projectId = Long.parseLong(repaymentResult.getSubject_id());
        kaoLaRealrePayment.setProjectId(projectId);
        KaoLaOrderInfo orderInfo = kaoLaOrderInfoMapperExt.selectByProjectId(projectId);
        if (orderInfo == null) {
            log.info("考拉理财还款回调--未查询到对应的订单记录信息!subject_id:{}", projectId);
            result.setFailureMessage("未查询到对应的订单记录信息!");
            return null;
        }
        // 借款订单号
        kaoLaRealrePayment.setLoanOrderId(orderInfo.getLoanOrderId());
        // 流水号,用户被动还款由考拉理财生成流水号
        kaoLaRealrePayment.setSerialNo(repaymentResult.getSerial_no());
        // 还款类型
        Byte repayType = repaymentResult.getType();
        Byte repayMethod = null;
        if (KaoLaLiCaiRepayTypeEnum.REPAY_NOMAL.getCode().equals(repayType)) {
            //正常还款
            repayMethod = KaoLaRealRepayment.RepayMethodEnum.NORMAL_REPAY.getType();
        } else if (KaoLaLiCaiRepayTypeEnum.REPAY_SETTLE.getCode().equals(repayType)) {
            //提前还款
            repayMethod = KaoLaRealRepayment.RepayMethodEnum.PRE_REPAY.getType();
        } else if (KaoLaLiCaiRepayTypeEnum.REPAY_ADVANCE.getCode().equals(repayType)) {
            //代偿
            repayMethod = KaoLaRealRepayment.RepayMethodEnum.OVERDUE_COMP.getType();
        } else if (KaoLaLiCaiRepayTypeEnum.REPAY_BUYBACK.getCode().equals(repayType)) {
            //考拉回购
            repayMethod = KaoLaRealRepayment.RepayMethodEnum.BUYBACK_REPAY.getType();
        } else if (KaoLaLiCaiRepayTypeEnum.REPAY_BATCHPAYMENT.getCode().equals(repayType)) {
            //考拉批扣
            repayMethod = KaoLaRealRepayment.RepayMethodEnum.REPAY_BATCHPAYMENT.getType();
        } else {
            log.info("考拉理财还款回调--不支持的还款类型", projectId);
            result.setFailureMessage("未查询到对应的订单记录信息!");
            return null;
        }
        kaoLaRealrePayment.setRepayMethod(repayMethod);
        kaoLaRealrePayment.setRepayType(repayType);
        // 借款人身份证
        Project project = projectMapper.selectByPrimaryKey(projectId);
        if (project == null) {
            log.info("考拉理财还款回调--未查询到对应的项目信息!subject_id:{}", projectId);
            result.setFailureMessage("未查询到对应的项目信息!");
            return null;
        }
        QueryUserBasicInfoRequestDTO requestDTO = new QueryUserBasicInfoRequestDTO();
        requestDTO.setUserId(project.getBorrowUserId());
        requestDTO.setType(QueryBasicInfoEnum.USER_ID);
        QueryBasicInfoResponseDTO queryBasicInfoResponseDTO = userBasicInfoDubboService.queryUserBasicInfo(requestDTO);

        if (queryBasicInfoResponseDTO == null) {
            log.info("考拉理财还款回调--未查询到对应的借款人信息!userId:{}", project.getBorrowUserId());
            result.setFailureMessage("未查询到对应的借款人信息!");
            return null;
        }
        // 借款人身份证
        kaoLaRealrePayment.setIdCard(queryBasicInfoResponseDTO.getIdcard());
        // 还款期数，如果是提前结清，期数为100
        Integer repayNo = repaymentResult.getRepay_no();
        if (KaoLaLiCaiRepayTypeEnum.REPAY_SETTLE.getCode().equals(repayType)) {
            repayNo = 100;
        }
        kaoLaRealrePayment.setRepayNo(repayNo);
        // 还款日期
        Date repayDate = DateUtils.formatDateWithLong(repaymentResult.getRepay_time(), DateUtils.SHOW_DATE_FORMAT_DD_MM_YYYYY);
        kaoLaRealrePayment.setRepayDate(DateUtils.format(repayDate, DateUtils.SHOW_DATE_FORMAT_DD_MM_YYYYY));
        // 还款总额
        kaoLaRealrePayment.setRepayAmount(repaymentResult.getAmount());
        // 还款本金
        kaoLaRealrePayment.setPrincipal(repaymentResult.getPrincipal());
        // 还款利息
        kaoLaRealrePayment.setInterest(repaymentResult.getInterest());
        // 利息分账
        kaoLaRealrePayment.setInterestSplit(repaymentResult.getInterest_split());
        // 罚息
        kaoLaRealrePayment.setOverdueInterest(repaymentResult.getOverdue_interest());
        // 用户被动还款
        kaoLaRealrePayment.setIsPassive(KaoLaLiCaiIsPassiveEnum.REPAY_PASSIVE.getCode());
        // 创建时间
        kaoLaRealrePayment.setCreateTime(new Date());
        kaoLaRealrePayment.setId(snowflakeIdWorker.nextId());
        kaoLaRealRepaymentMapperExt.insertSelective(kaoLaRealrePayment);

        result.setRet(Result.SUCCESS_RET);
        return kaoLaRealrePayment;
    }

    /**
     * 还款成功天秤回流
     *
     * @param dto
     */
    public void sendTianCheng(RefundCallBackForAccountDTO dto) {
        try {
            ProjectRefundEventRequest req = new ProjectRefundEventRequest();
            List<ProjectRefundEventRequestDetail> list = new ArrayList<ProjectRefundEventRequestDetail>();
            List<ProjectBorrowerPlan> projectBorrowerPlans = projectBorrowerPlanMapperExt.queryProjectBorrowerPlanListPeriodAscByProjectIdAndBorrowerUserId(dto.getProjectId(), dto.getBorrowerUserId());
            projectBorrowerPlans.forEach(biz -> {
                ProjectRefundEventRequestDetail detail = new ProjectRefundEventRequestDetail();
                detail.setCurrentPeriods(biz.getCurrentPeriod());
                detail.setProjectId(biz.getProjectId());
                detail.setUserId(biz.getBorrowerUserId());
                detail.setTotalPeriods(biz.getTotalPeriod());
                int overDueDay = RepaymentUtil.getOverdueDay(biz.getRefundDate(), new Date());
                if (overDueDay > 0) {
                    detail.setOverdueDay(overDueDay);
                    detail.setOverdueAmount(biz.getCapital().add(biz.getInterest()).subtract(biz.getRefundedCapital()).subtract(biz.getRefundedInterest()));
                }
                detail.setRealCostAmount(biz.getRefundedCapital());
                detail.setRealRefundInterest(biz.getRefundedInterest());
                detail.setOverdueFine(biz.getPenaltyFee());
                if (biz.getGenerateSource() == 1) {
                    detail.setStatus(ProjectPlanStatusEnum.BADREFUND.getTianchengStatus());
                } else {
                    detail.setStatus(ProjectPlanStatusEnum.enumOf(biz.getRefundStatus()).getTianchengStatus());
                }
                detail.setRealRefundDate(biz.getOverTime().getTime());
                detail.setUpdateTime(biz.getRefundDate().getTime());
                list.add(detail);
            });

            ProjectBorrowerAmountSumDTO amountSumDTO = projectBorrowerPlanMapperExt.sumProjectBorrowerPlanAmountByProjectIdAndBorrowerUserId(dto.getProjectId(), dto.getBorrowerUserId());
            Assert.notNull(amountSumDTO, "数据异常，projectBorrowerAmountSumDTO不可空");
            req.setProjecterPayment(list);
            req.setUserId(dto.getBorrowerUserId());
            req.setProjectId(dto.getProjectId());
            req.setUpdateTime(DateTime.now().getMillis());
            req.setBorrowedAmount(amountSumDTO.getBorrowedAmount());
            BigDecimal doneAmount = amountSumDTO.getRefundedCapital().add(amountSumDTO.getRefundedInterest()).add(amountSumDTO.getRefundedManagementFee())
                    .add(amountSumDTO.getRefundedGuaranteeFee()).add(amountSumDTO.getRefundedPenaltyFee());
            req.setDoneAmount(doneAmount);
            BigDecimal totalAmount = amountSumDTO.getBorrowedAmount().add(amountSumDTO.getInterest()).add(amountSumDTO.getManagementFee()).add(amountSumDTO.getGuaranteeFee()).add(amountSumDTO.getPenaltyFee());
            req.setLateAmount(totalAmount.subtract(doneAmount));
            RpcContext.getContext().asyncCall(new Runnable() {
                @Override
                public void run() {
                    //天秤回流
                    tianChengRefundEventService.refundSucceed(req);
                }
            });
        } catch (Exception e) {
            log.error("sendTianCheng Exception,", e);
        }
    }


    @Autowired
    private ProjectMapperExt projectMapperExt;

    @Autowired
    private RabbitTemplate rabbitTemplate;


    public void sendMqMsgToApp(RefundCallBackForAccountDTO dto) {
        try {
            Project project = projectMapperExt.selectByPrimaryKey(dto.getProjectId());
            log.info("考拉理财还款回调--app通知发送,projectId={}", project.getProjectId());
            ProjectBorrowerPlan projectBorrowerPlan = projectBorrowerPlanMapperExt.selectBorrowerPlanByProjectIdAndCurrentPeriod(dto.getProjectId(), dto.getCurrentPeriod());
            FollowWorkTaskRepaymentDTO followWorkTaskRepaymentDTO = new FollowWorkTaskRepaymentDTO();
            followWorkTaskRepaymentDTO.setBorrowerPlanId(projectBorrowerPlan.getId());
            followWorkTaskRepaymentDTO.setOverState(projectBorrowerPlan.getRefundStatus());
            followWorkTaskRepaymentDTO.setRepaymentAmount(projectBorrowerPlan.getCapital().add(projectBorrowerPlan.getInterest()).add(projectBorrowerPlan.getPenaltyFee())
                    .add(projectBorrowerPlan.getManagementFee()).add(projectBorrowerPlan.getGuaranteeFee()));
            followWorkTaskRepaymentDTO.setRepaymentDate(projectBorrowerPlan.getRefundDate());
            rabbitTemplate.convertAndSend(RabbitConstant.Exchange.FOLLOW_WORK_TASK_REPAYMENT, RabbitConstant.RoutingKey.FOLLOW_WORK_TASK_REPAYMENT,
                    followWorkTaskRepaymentDTO);
        } catch (Exception e) {
            log.error("send to app followWorkTaskRepayment failed.", e);
        }
    }

    private void repaymentSuccessPushLetterToBorrowerAsyn(ProjectBorrowerSummary projectBorrowerSummary, RepaymentTypeLetterEnum repaymentTypeLetterEnum, NotifyRepaymentResult repaymentResult) {
        log.info("repaymentSuccessPushLetterToBorrowerAsyn.projectBorrowerSummary={}", JSON.toJSONString(projectBorrowerSummary));
        try {
            CompletableFuture.runAsync(() -> this.repaymentSuccessPushLetterToBorrower(projectBorrowerSummary, repaymentTypeLetterEnum, repaymentResult));
        } catch (Exception e) {
            log.error("repaymentSuccessPushLetterToBorrowerAsyn异常，projectBorrowerSummary={}", JSON.toJSONString(projectBorrowerSummary), e);
        }
    }


    /**
     * 还款成功发送消息给借款人
     *
     * @param projectBorrowerSummary
     */
    public void repaymentSuccessPushLetterToBorrower(ProjectBorrowerSummary projectBorrowerSummary, RepaymentTypeLetterEnum repaymentTypeLetterEnum, NotifyRepaymentResult repaymentResult) {
        Long projectId = projectBorrowerSummary.getProjectId();
        Integer currentPeriod = projectBorrowerSummary.getCurrentPeriod();
        Integer totalPeriod = projectBorrowerSummary.getTotalPeriod();

        RepaymentSuccessDTO repaymentSuccessDTO = new RepaymentSuccessDTO();
        repaymentSuccessDTO.setUserId(projectBorrowerSummary.getBorrowerUserId());
        repaymentSuccessDTO.setProjectId(projectId);
        repaymentSuccessDTO.setProjectTitle(projectBorrowerSummary.getProjectTitle());
        repaymentSuccessDTO.setCurrentPeriod(currentPeriod);
        repaymentSuccessDTO.setTotalPeriods(totalPeriod);
        repaymentSuccessDTO.setRepaymentTypeLetterEnum(repaymentTypeLetterEnum);
        repaymentSuccessDTO.setSuccessRepaymentAmount(repaymentResult.getAmount());
        messageSendDubboService.sendLetterForRepaymentFromKaola(repaymentSuccessDTO);
    }


}
